// g++ json.cpp -o json -ljsoncpp

#include<iostream>
#include<string>
#include<sstream>
#include<memory>
#include<jsoncpp/json/json.h>

bool serialize(const Json::Value& value, std::string& body)
{
    std::stringstream ss;
    Json::StreamWriterBuilder swb;
    std::unique_ptr<Json::StreamWriter> sw(swb.newStreamWriter());
    int ret = sw->write(value, &ss);
    if(ret != 0){
        std::cout << "Json serialize failed" << std::endl;
        return false;
    } else {
        body = ss.str();
        return true;
    } 
}

bool unserialize(const std::string& body, Json::Value& value)
{
    Json::CharReaderBuilder crb;
    std::unique_ptr<Json::CharReader> cr(crb.newCharReader());
    std::string errs;
    bool ret = cr->parse(body.c_str(),body.c_str()+body.size(),&value, &errs);
    if(!ret){
        std::cout << "Json unserialize failed" << errs << std::endl;
        return false;
    } else {
        return true;
    }
}

int main()
{
    const char* name = "小嘎";
    int age = 23;
    const char* sex = "男";
    float score[3] = { 88, 77.5, 66};

    Json::Value student;
    student["姓名"] = name;
    student["年龄"] = 23;
    student["性别"] = sex;
    for(auto i:score){
        student["成绩"].append(i);
    }

    Json::Value fov;
    fov["运动"] = "羽毛球";
    fov["书籍"] = "明朝那些事";
    student["爱好"] = fov;

    std::string body;
    serialize(student, body);
    std::cout << body << std::endl;

    // Json::Value root;
    // unserialize(body,root);
    // std::cout << root << std::endl;

    std::string str =R"({"姓名":"小黑", "年龄":22, "成绩":[88,99,88],
            "爱好":{"运动":"篮球","书籍":"三国演义"}})";
    Json::Value stu;
    bool ret = unserialize(str,stu);
    if(ret == false)
        return -1;
    std::cout << "姓名: " << stu["姓名"].asString() << std::endl;
    std::cout << "年龄: " << stu["年龄"].asFloat() << std::endl;
    int sz = stu["成绩"].size();
    for(int i = 0; i < sz; i++){
        std::cout << "成绩:" << stu["成绩"][i].asInt() << std::endl;
    }

    // 打印爱好信息
    std::cout << "爱好-运动："  << stu["爱好"]["运动"].asString() << std::endl;
    std::cout << "爱好-书籍 "   << stu["爱好"]["书籍"].asString() << std::endl;

    std::cout << "爱好：" << std::endl;
    Json::Value hobbies = stu["爱好"];
    Json::Value::Members members = hobbies.getMemberNames();
    for (const auto& member : members){
        std::cout << "  " << member << " : " << hobbies[member].asString() << std::endl;
    }


    return 0;
}